package com.umessage.hotel.controller;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;

import com.umessage.common.controller.BaseController;
import com.umessage.common.util.SimpleSmsUtil;
import com.umessage.hotel.domain.BreakfastCoupon;
import com.umessage.hotel.domain.HotelCrontab;
import com.umessage.hotel.domain.HotelInfo;
import com.umessage.hotel.domain.OrderInfo;
import com.umessage.hotel.domain.WxCfg;
import com.umessage.hotel.service.BreakfastCouponService;
import com.umessage.hotel.service.DepositOrderService;
import com.umessage.hotel.service.HotelCrontabService;
import com.umessage.hotel.service.HotelInfoService;
import com.umessage.hotel.service.MemberInfoService;
import com.umessage.hotel.service.OrderInfoService;
import com.umessage.hotel.service.WxCfgService;
import com.umessage.hotel.util.HotelConstant;
import com.umessage.hotel.util.TimeUtil;
import com.umessage.system.service.UserService;

/**
 * 定时任务
 * @author zmj
 *
 */

@Controller 
@EnableScheduling
public class ScheduledController  extends BaseController  {
	private static Logger logger = LoggerFactory.getLogger(ScheduledController.class);
	
	@Autowired
	OrderInfoService orderInfoService ;
	@Autowired
	private WxCfgService wxCfgService;
	@Autowired
	private UserService userService;
	@Autowired
	private HotelInfoService hotelInfoService;
	@Autowired
	private HotelCrontabService hotelCrontabService;
	@Autowired
	private SimpleSmsUtil simpleSmsUtil;
	@Autowired
	private MemberInfoService memberInfoService;
	@Autowired
	private DepositOrderService depositOrderService;
	@Autowired
	private BreakfastCouponService breakfastCouponService;
	
	DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
	
	private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	/**
	 * 每天18执行，将“已确认”订单更新为“已入住”  (1.2剔除)
	 */
//	@Scheduled(cron = "0 0/30 * * * ?")
	/*public void pushDataScheduled(){
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String baseDate = sdf.format(date);
		String startTime = baseDate +" 00:00:00";
	    String endTime = baseDate +" 23:59:59";
	    String orderStatus = "3"; 
	    String oldStatus ="1";
	    orderInfoService.updateByOrderStatusSelective(orderStatus,startTime,endTime,oldStatus);
	    
	}*/
	
	/**
	 * 定时器总控
	 */
	@Scheduled(cron = "0 0 * * * ?")
	public void scheduled(){
		Date current = new Date() ;
		int currentHour = TimeUtil.getNowHour(current) ;
		// 取出所有为有效的定时任务。
		List<HotelCrontab> hotelCrontabs = hotelCrontabService.findHotelCrontabs(1) ;
		for(int i = 0 ; i < hotelCrontabs.size() ; i ++) {
			HotelCrontab hc = hotelCrontabs.get(i) ;
			int status = hc.getStatus() ;
			int taskId = hc.getTaskId() ;
			String hotelId = hc.getHotelId() +"" ;
			// 12小时任务每小时执行一次
			//if(taskId == HotelConstant.HOTEL_CRONTAB_TASK_4){
			//	cancleTimeout12PayOrder(hotelId, hc.getRunTimes()) ;
			//}
			
			if(currentHour != hc.getRunTimes()) {
				continue ;
			}
			// 执行每天的定时运行的任务
			if(taskId == HotelConstant.HOTEL_CRONTAB_TASK_1) {
				waitConfirmOrderScheduled(hotelId,hc) ;
			}else if(taskId == HotelConstant.HOTEL_CRONTAB_TASK_2) {
				overOrderScheduled(hotelId,hc) ;
			}else if(taskId == HotelConstant.HOTEL_CRONTAB_TASK_3) {
				sendHotelStatisticsByMsg(hotelId,hc) ;
			}
		}
	}
	
	/**
	 * 订单在固定期限(0.5小时-6小时)内未确认，自动进行确认
	 */
	@Scheduled(cron = "0 */15 * * * ?")
	public void confirmTimeoutPayOrder(){
		long currentTimeMillis = System.currentTimeMillis();
		// 取出所有为有效的定时任务。
		List<HotelCrontab> hotelCrontabs = hotelCrontabService.findHotelCrontabs(1) ;
		for(int i = 0 ; i < hotelCrontabs.size() ; i ++) {
			HotelCrontab hc = hotelCrontabs.get(i) ;
			// 12小时任务每小时执行一次
			if(hc.getTaskId() != HotelConstant.HOTEL_CRONTAB_TASK_4){
				continue ;
			}
			String hotelId = hc.getHotelId() +"" ;
			double delayHours = hc.getRunTimes() ;
			
			currentTimeMillis -= delayHours * 60 * 60 * 1000; 
			Date date = new Date(currentTimeMillis);
			String beginTime = simpleDateFormat.format(date); 
			/**
			 * 查询超过规定的小时内未确认的订单*/
			try {
				List<OrderInfo> list=  orderInfoService.select12hTimeoutOrderByHotelId(beginTime, hotelId);
				if(null !=list && list.size()>0){
					for (OrderInfo orderInfo : list) {
						OrderInfo order = orderInfoService.selectByKey(orderInfo.getOrderId());
						//非待确认 //防止中途确认
						if(!order.getOrderStatus().equals("0")){
							continue;
						}
						
						// 自动把订单进行确认
						order.setOrderStatus("1");
						orderInfoService.updateByOrderSnSelective(order) ;
						
						// 向会员和酒店员工发送确认消息
						List<String> mobileList = userService.findConfirmUserMobileList(order.getHotelId().toString());
						HotelInfo hotel = hotelInfoService.selectByKey(order.getHotelId().toString());
						//给会员发送短信通知
						orderInfoService.sendSms("1", order);
						//给酒店员工发送确认消息
						if (mobileList != null && mobileList.size() > 0) {
							for(String mobile : mobileList) {
								try {
									String msg = "酒店有超过" + hc.getRunTimes()+"小时未确认订单已被自动确认，订单编号：" + order.getOrderSn() 
									+ "，房型：" + order.getName()
									+ ",房间数量：" + order.getRoomCount()
									+ "，入住时间：" + df.format(df.parse(order.getCheckinTime()));
									simpleSmsUtil.sendMsg(mobile, hotel.getHotelName(), msg);
								} catch (ParseException e) {
									e.printStackTrace();
								}
							}
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 18时,当天入住待确认  转为取消
	 * @param hc 
	 */
	//@Scheduled(cron = "0 0 18 * * ? ")
	public void waitConfirmOrderScheduled(String hotelId, HotelCrontab hc){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String baseDate = sdf.format(new Date());
		String startTime = baseDate +" 00:00:00";
	    String endTime = baseDate +" 23:59:59";
	    String oldStatus ="0";
	    try {
			//查询当天待确认的订单
			List<OrderInfo> orderList = orderInfoService.findOrderToDayByHotelId(oldStatus, startTime, endTime, hotelId);
			if (null != orderList && orderList.size() > 0) {
				for (OrderInfo orderInfo : orderList) {//取消并退款
					WxCfg queryWxCfg = wxCfgService.queryWxCfg(orderInfo.getHotelId() + "", "1");
					String wxcfgid = (queryWxCfg == null ? null : queryWxCfg.getWxcfgid());
					orderInfoService.cancelOrderByAuto(wxcfgid, HotelConstant.OPERATOR_TYPE_HOTEL, "4", orderInfo, true,
							"超过"+hc.getRunTimes()+"时自动取消");
					//给会员发送短信通知
					orderInfoService.sendSms("2", orderInfo);
					
					List<String> mobileList = userService.findConfirmUserMobileList(orderInfo.getHotelId().toString());
					HotelInfo hotel = hotelInfoService.selectByKey(orderInfo.getHotelId().toString());
					logger.info("超过"+hc.getRunTimes()+"时,当天入住 待确认  转为取消"+orderInfo.getOrderId());
					//给酒店员工发送消息
					if (mobileList != null && mobileList.size() > 0) {
						for (String mobile : mobileList) {
							String msg = "酒店有超过"+hc.getRunTimes()+"时待确认订单已被取消，订单编号：" + orderInfo.getOrderSn() + "，房型："
									+ orderInfo.getName() + ",房间数量：" + orderInfo.getRoomCount() + "，入住时间："
									+ df.format(df.parse(orderInfo.getCheckinTime()));
							simpleSmsUtil.sendMsg(mobile, hotel.getHotelName(), msg);
						}
					}
				}
			} 
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage(),e);
		}
	}
	/**
	 * 12点   当天离店  已确认 改为 已结束
	 * @param hc 
	 */
	//@Scheduled(cron = "0 0 12 * * ?")
	public void overOrderScheduled(String hotelId, HotelCrontab hc){
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			String baseDate = sdf.format(new Date());
			String startTime = baseDate + " 00:00:00";
			String endTime = baseDate + " 23:59:59";
			String oldStatus = "1";
			String orderStatus = "3";
			orderInfoService.updateByOrderStatusOverByHotelId(orderStatus, startTime, endTime, oldStatus, hotelId);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage(),e);
		}
	}
	
	/**
	 * 超过三十分钟未支付订单取消/分
	 */
	@Scheduled(cron = "0 0/1 * * * ?")
	public void cancleUnPayOrder(){
		try {
			long currentTimeMillis = System.currentTimeMillis();
			currentTimeMillis -= 30 * 60 * 1000; 
			Date date = new Date(currentTimeMillis);
			String beginTime = simpleDateFormat.format(date); 
			List<OrderInfo> list=  orderInfoService.select30TimeoutOrder(beginTime);
			if(null !=list && list.size()>0){
				for (OrderInfo orderInfo : list) {
					OrderInfo order = orderInfoService.selectByKey(orderInfo.getOrderId());
					if (order != null && order.getPayType() > 1 && order.getPayStatus() == 0) {
						order.setOrderStatus("2");//取消状态
						order.setCancelTime(new Date());
						order.setCancelType(1);
						order.setCancelReason("超时支付,自动取消");
						order.setCancelPerson("4");//默认用户
						orderInfoService.updateNotNull(order);
					}
					logger.info("30分钟自动取消,订单id:" + order.getOrderId() + "******" + df.format(new Date()));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("执行取消订单定时器失败"+e.getMessage(), e);
		}
	}
	
	/**
	 * 超过十二小时未确认订单
	 */
	//@Scheduled(cron="0 0/15 * * * ?")
	public void cancleTimeout12PayOrder(String hotelId, Integer delayHours){
		long currentTimeMillis = System.currentTimeMillis();
		currentTimeMillis -= delayHours * 60 * 60 * 1000; 
		Date date = new Date(currentTimeMillis);
		String beginTime = simpleDateFormat.format(date); 
		try {
			List<OrderInfo> list=  orderInfoService.select12hTimeoutOrderByHotelId(beginTime, hotelId);
			if(null !=list && list.size()>0){
				for (OrderInfo orderInfo : list) {
					OrderInfo order = orderInfoService.selectByKey(orderInfo.getOrderId());
					//非待确认 
					if( ! order.getOrderStatus().equals("0")){continue;} //防止中途确认
					
					//进行取消退款
					WxCfg queryWxCfg = wxCfgService.queryWxCfg(order.getHotelId() + "", "1");
					String wxcfgid = (queryWxCfg == null ? null : queryWxCfg.getWxcfgid());
					orderInfoService.cancelOrderByAuto(wxcfgid, HotelConstant.OPERATOR_TYPE_HOTEL, "4", order, true,
							"超过"+delayHours+"小时自动取消");
					
					List<String> mobileList = userService.findConfirmUserMobileList(order.getHotelId().toString());
					HotelInfo hotel = hotelInfoService.selectByKey(order.getHotelId().toString());
					
					//给会员发送短信通知
					orderInfoService.sendSms("2", order);
					//给酒店员工发送确认消息
					if (mobileList != null && mobileList.size() > 0) {
						for(String mobile : mobileList) {
							try {
								String msg = "酒店有超过"+delayHours+"小时未确认订单已被取消，订单编号：" + order.getOrderSn() 
										+ "，房型：" + order.getName()
										+ ",房间数量：" + order.getRoomCount()
										+ "，入住时间：" + df.format(df.parse(order.getCheckinTime()));
								simpleSmsUtil.sendMsg(mobile, hotel.getHotelName(), msg);
							} catch (ParseException e) {
								e.printStackTrace();
							}
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 10点发送前天
	 * @param hc 
	 */
	//@Scheduled(cron="0 0 10 * * ?")
	public void sendHotelStatisticsByMsg(String hotelId, HotelCrontab hc){
		String pastDate = TimeUtil.getPastDate(1).substring(0, 10).replace("/", "-");
		String startTime = pastDate+" 00:00:00";
		String endTime = pastDate+" 23:59:59";
		//新增用户
		Integer newUser = memberInfoService.getCountNewMemberByDate(hotelId, "0", startTime, endTime);
		//统计新增会员
		Integer newVip = memberInfoService.getCountNewMemberByDate(hotelId, "1", startTime, endTime);
		//订单量
		Integer countOrders = orderInfoService.countOrders(hotelId, "3", startTime, endTime);
		
		BigDecimal depositMoney = this.depositOrderService.taotalPay(hotelId, startTime, endTime);
		depositMoney = depositMoney==null? BigDecimal.ZERO:depositMoney; 
		BreakfastCoupon coupon=new BreakfastCoupon();
		coupon.setHotelId(hotelId);
		coupon.setValidDate(pastDate);
		Integer check=this.breakfastCouponService.countCheckToday(coupon);
		coupon.setType("1");//赠送即发放
		Integer countType1=this.breakfastCouponService.countNumTodayByType(coupon);
		coupon.setType("2");//购买
		Integer countType2=this.breakfastCouponService.countNumTodayByType(coupon);
		try {
			//查询消息通知人员
			List<String> mobileList = userService.findMsgUserMobileList(hotelId);
			if(mobileList != null && mobileList.size()>0){
				HotelInfo hotel = hotelInfoService.selectByKey(hotelId);
				for (String mobile : mobileList) {
					StringBuilder sb = new StringBuilder();
					sb.append("酒店昨日数据如下：新增用户数:"+newUser+"、新增会员数: "+newVip+"、成交订单数:"+countOrders+"、当日收益数:"+depositMoney+"、早餐发放数:"+countType1+"、早餐核销数:"+countType2+"、早餐购买数:"+check);
					simpleSmsUtil.sendMsg(mobile, hotel.getHotelName(), sb.toString());
					logger.info(hotel.getHotelName()+"10点定时统计短信发送成功"+mobile);
				}
			}
		} catch (Exception e) {
			logger.error("10点定时统计短信发送失败"+e.getMessage(), e);
			e.printStackTrace();
		}
	}
}
